/**
 * Copyright (c) 2008, Julien PORTALIER
 * http://featherphp.googlecode.com/
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 */

DatePicker = new Class(
{
	initialize: function(input)
	{
		this.input  = $(input);
		this.type   = input.hasClass('time') ? 'time' :
			(input.hasClass('date') ? 'date' : 'datetime');
		
		this.picker = new Dialog.Picker(this.input, {
			'onDisplay': this.openCalendar.bind(this),
			'setWidth':  false
		});
		
		this.today    = new Date();
		this.months   = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
		this.weekdays = ['su', 'mo', 'tu', 'we', 'th', 'fr', 'sa', 'su'];
	},
	
	openCalendar: function()
	{
		this.setDateTime(this.input.value);
		this.selected = this.date;
		this._setCalendar();
	},
	
	setPreviousMonth: function()
	{
		this.setDateTime(this._format_date(this.date.getFullYear(), this.date.getMonth(), this.date.getDate()));
		this._setCalendar();
	},
	
	setNextMonth: function()
	{
		this.setDateTime(this._format_date(this.date.getFullYear(), this.date.getMonth() + 2, this.date.getDate()));
		this._setCalendar();
	},
	
	setDateTime: function(datetime)
	{
		datetime  = datetime.trim();
		var date  = datetime.substring(0, 10).split('-');
		this.date = new Date(date[0], date[1] - 1, date[2]);
	},
	
	_setCalendar: function()
	{
		var today = Date();
		var first = new Date(this.date.getFullYear(), this.date.getMonth(), 1);
		
		// date picker
		var html = '<table>' +
			'<tr class="date">' +
				'<th class="before">«</th>' +
				'<th class="now" colspan="5"> ' +
					this.months[this.date.getMonth()] + ' ' +
					this.date.getFullYear() +
				' </th>' +
				'<th class="after">»</th>' +
			'</tr><tr class="weekdays">';
		for (i=0; i<7; i++) {
			html += '<td>' + this.weekdays[i] + '</td>';
		}
		html += '</tr><tr class="days">';
		
		var wd = 0;
		var nb = this._daysInMonth(first.getFullYear(), first.getMonth() - 1);
		for (var d = nb - first.getDay() + 1; d <= nb; d++)
		{
			html += '<td class="wrong">' + d + '</td>';
			wd++;
		}
		
		for (var d=1; d <= this._daysInMonth(this.date.getFullYear(), this.date.getMonth()); d++)
		{
			var classes = '';
			if (this.today.getFullYear() == this.date.getFullYear()
				&& this.today.getMonth() == this.date.getMonth()
				&& this.today.getDate()  == d)
			{
				classes = 'today';
			}
			if (this.date.getFullYear() == this.selected.getFullYear()
				&& this.date.getMonth() == this.selected.getMonth()
				&& this.date.getDate()  == d)
			{
				classes += ' selected ';
			}
			
			html += '<td' + (classes != '' ? ' class="' + classes + '"' : '') + '>' + d + '</td>';
			
			wd++;
			if (wd == 7)
			{
				wd = 0;
				html += '</tr><tr class="days">';
			}
		}
		
		if (wd > 0)
		{
			for (var d = 1; d < 8 - wd; d++) {
				html += '<td class="wrong">' + d + '</td>';
			}
		}
		
		html += '</tr></table>';
		
		// content for picker
		var div = new Element('div', {'class': 'date-picker'}).set('html', html);
		this.picker.setContent('element', div);
		
		// events
		div.getElement('table').addEvent('click', this._action.bind(this));
	},
	
	_action: function(evt)
	{
		var tr = evt.target.getParent('tr');
		
		if (tr.hasClass('days'))
		{
			// selected a date
			var td    = evt.target;
			var day   = td.get('text');
			var month = td.hasClass('wrong') ?
				day < 15 ?
					this.date.getMonth() + 2 :
					this.date.getMonth() :
				this.date.getMonth() + 1;
			
			// format value
			var value = this._format_date(this.date.getFullYear(), month, day);
			if (this.type == 'datetime') {
				value += this.input.value.substring(10);
			}
			this.input.value = value;
			
			// hides calendar
			this.picker.hide();
		}
		else if(tr.hasClass('date'))
		{
			// navigates throught months
			if (evt.target.hasClass('before'))
			{
				this.setPreviousMonth();
				evt.stop();
			}
			else if (evt.target.hasClass('after'))
			{
				this.setNextMonth();
				evt.stop();
			}
		}
	},
	
	_daysInMonth: function(year, month)
	{
		// leap year?
		if (month == 1 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) {
			return 29;
		}
		
		// standard year
		var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
		return days[month];
	},
	
	_format_date: function(y, m, d)
	{
		return y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d);
	},
	
	_format_time: function(h, m, s)
	{
		return (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
	}
});

window.addEvent('domready', function()
{
	$$('input.datetime, input.date').each(function(input) {
		new DatePicker(input);
	});
});
